package com.iss.card;

import java.util.Collection;
import java.util.HashMap;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.iss.card.CardController.EventHandler;
import com.iss.card.CardController.EventInfo;
import com.iss.card.CardController.EventType;
import com.iss.card.cache.ImageCache;
import com.iss.card.cache.ImageDataManager;
import com.iss.card.common.ApplicationManager;
import com.iss.card.common.CommonValue;
import com.iss.card.common.FunctionUtil;
import com.iss.card.common.IBackKeyListener;
import com.iss.card.common.Tools;
import com.iss.card.common.UtilityHelper;
import com.iss.card.mapv2.BDLocationClient;
import com.iss.card.mapv2.MyLocationManager;
import com.iss.card.model.CityDataManager;
import com.iss.card.model.StoreTypeInfo;
import com.iss.card.view.account.AccountFragment;
import com.iss.card.view.collent.CollentFragment;
import com.iss.card.view.model.CityBean;
import com.iss.card.view.mycard.MyCardFragment;
import com.iss.card.view.mycard.UnpayFormFragment;
import com.iss.card.view.mycard.UnpayFormFragment.UnpayFormClickListener;
import com.iss.card.view.store.CityListFragment;
import com.iss.card.view.store.StoreFilterFragment;
import com.iss.card.view.store.StoreFragment;

/**
 * main activity.
 */
public class CardActivity extends FragmentActivity implements EventHandler,
		IBackKeyListener, UnpayFormClickListener {

	private static final String TAG = CardActivity.class.getSimpleName();
	/** store */
	public static final String FRAGMENT_STORE_NAME = "store_content";
	/** @ me */
	private static final String FRAGMENT_ACCOUNT_NAME = "account_content";
	/** my card bag */
	private static final String FRAGMENT_CARDBAG_NAME = "scardbag_content";
	/** my collection */
	private static final String FRAGMENT_COLLENT_NAME = "collent_content";
	/** city list */
	private static final String FRAGMENT_CITYLIST_NAME = "citylist_content";

	private static final String FRAGMENT_STORE_FILTER_NAME = "store_filter_name";

	private static final String FRAGMENT_UNPAY_FORM_LIST = "unpay_form_fragment";

	private static final int HANDLER_KEY = 0;
	private CardController mController;

	private static HashMap<String, Fragment> fragmentMap = new HashMap<String, Fragment>();
	private FragmentManager mFragmentManager;

	private Fragment frgStore;
	private Fragment frgCard;
	private Fragment frgCollent;
	private Fragment frgAccount;
	private Fragment frgCityList;
	private Fragment unpayFormFrag;

	ImageView logoImage;
	LinearLayout mainLayout;

	private Context mContext;

	/** for @ me group view & city list fragment */
	private EventInfo mEventInfo;

	private EventHandler mEventHandler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		long maxMemory = Runtime.getRuntime().maxMemory();
		Log.d(TAG, "onCreate: maxSize=" + maxMemory + ", " + (maxMemory >> 20) + "M");
		setContentView(R.layout.activity_main);
		UtilityHelper.instance().setContext(this);
		// Tools.openGPSSettings(this);
		logoImage = (ImageView) findViewById(R.id.main_image);
		mainLayout = (LinearLayout) findViewById(R.id.main_layout);
		this.mContext = this.getApplicationContext();
		ApplicationManager.SCREEN_WIDTH = ApplicationManager
				.getScreenWidth(this);
		ApplicationManager.SCREEN_HEIGHT = ApplicationManager
				.getScreenHeight(this);
		mFragmentManager = this.getSupportFragmentManager();
		ImageDataManager.instance().initialize(mContext);
		mLocClient = ((BDLocationClient)getApplication()).mLocationClient;
		mEventHandler = new EventHandler(Looper.getMainLooper());
		

		// This needs to be created before setContentView
		mController = CardController.getInstance(this);

		// Must register as the first activity because this activity can modify
		// the list of event handlers in it's handle method. This affects who
		// the rest of the handlers the controller dispatches to are.
		mController.registerFirstEventHandler(HANDLER_KEY, this);

		frgStore = new StoreFragment();
		frgCard = new MyCardFragment();
		frgCollent = new CollentFragment();
		frgAccount = new AccountFragment();
		unpayFormFrag = new UnpayFormFragment();
	}

	@Override
	protected void onResume() {
		super.onResume();
		mEventHandler
		.sendEmptyMessage(EventHandler.MSG_STAGE_ENVIRONMENT_CHECK);
		Log.d(TAG, "onResume");
		if (ApplicationManager.LAST_VIEW_FROM_MAIN
				.equals(ApplicationManager.LOGIN_FROM_MYCARD)
				&& FunctionUtil.isUserLogIn()) {
			FunctionUtil
					.setCurrentPageIndex(CommonValue.EnumPageIndex.EPageCardList);
			FragmentTransaction ft = mFragmentManager.beginTransaction();
			removeFragment(frgCityList, FRAGMENT_CITYLIST_NAME);
			if (frgCard == null) {
				frgCard = new MyCardFragment();
			}
			addFragment(ft, frgCard, FRAGMENT_CARDBAG_NAME);
			showFragment(frgCard, frgStore, frgCollent, frgAccount);
			ApplicationManager.LAST_VIEW_FROM_MAIN = "";
		}
	}

	/**
	 * process back key event.
	 */
	@Override
	public void onBackPressed() {
		Log.d(TAG, "onBackPressed");

		if (mEventInfo != null) {
			if (mEventInfo.eventType == EventType.ACCOUNT_TITLE_CHANGE_PAS) {// change
																				// password.
				mController.sendEvent(EventType.ACCOUNT_TITLE_ACCOUNT);
				return;
			} else if (mEventInfo.eventType == EventType.ACCOUNT_CITYLIST) {// the
																			// back
																			// event
																			// for
																			// city
																			// list.
				mController.sendEvent(EventType.STORE_CONTENT);
				return;
			} else if (mEventInfo.eventType == EventType.ACCOUNT_FIND_PASSWORD
					|| mEventInfo.eventType == EventType.ACCOUNT_TITLE_REGISTER) {
				mController.sendEvent(EventType.ACCOUNT_TITLE_LOGIN);
				return;
			} else if (mEventInfo.eventType == EventType.UNPAY_ORDER_LIST) {

				FragmentTransaction ft = mFragmentManager.beginTransaction();
				addFragment(ft, unpayFormFrag, FRAGMENT_UNPAY_FORM_LIST);
				showFragment(frgCard, unpayFormFrag, frgStore, frgCollent,
						frgAccount);
				return;
			}
		}

		mController.deregisterAllEventHandlers();
		CardController.removeInstance(mContext);
		finish();
	}

	@Override
	protected void onPause() {
		super.onPause();
		Log.d(TAG, "onPause");
	}

	@Override
	protected void onStart() {
		super.onStart();
		Log.d(TAG, "onStart");
	}

	@Override
	protected void onStop() {
		super.onStop();
		Log.d(TAG, "onStop");
	}

	private void showFragment(Fragment showFragment, Fragment... cloesFrg) {

		FragmentTransaction ft = mFragmentManager.beginTransaction();
		ft.show(showFragment);

		for (Fragment fragment : cloesFrg) {
			if (fragment == null) {
				continue;
			}
			if (fragment.isVisible()) {
				ft.hide(fragment);
			}
		}
		ft.commit();
	}

	private void addFragment(FragmentTransaction transaction,
			Fragment fragment, String fragName) {
		if (fragmentMap.get(fragName) == null) {
			fragmentMap.put(fragName, fragment);
			transaction.add(R.id.main_frame, fragment);
			transaction.commit();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestroy");
		fragmentMap.clear();
		CommonValue.USERID = "";
		MyLocationManager.instance().destroy();
		if (mLocClient != null) {
			mLocClient.stop();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent data_intent) {
		super.onActivityResult(requestCode, resultCode, data_intent);
		Log.d(TAG, "onActivityResult: requestCode=" + requestCode
				+ ", resultCode=" + resultCode);
		switch (requestCode) {
		case ApplicationManager.REQCODE_COLLECT: // not logined in.
			mController.sendEvent(EventType.ACCOUNT_CONTENT);
			break;
		case ApplicationManager.REQCODE_NETWORK_SETTING:
			mEventHandler.sendEmptyMessage(EventHandler.MSG_STAGE_INITIALIZE);
			break;
		default:
			break;
		}
	}

	@Override
	public long getSupportedEventTypes() {
		return EventType.STORE_CONTENT | EventType.CARDBAG_CONTENT
				| EventType.COLLENT_CONTENT | EventType.ACCOUNT_CONTENT
				| EventType.ACCOUNT_TITLE_ACCOUNT
				| EventType.ACCOUNT_TITLE_LOGIN
				| EventType.ACCOUNT_TITLE_REGISTER
				| EventType.ACCOUNT_FIND_PASSWORD
				| EventType.ACCOUNT_TITLE_CHANGE_PAS
				| EventType.ACCOUNT_CITYLIST
				| EventType.ACCOUNT_DELETE_FRAGMENT | EventType.STORE_FILTER
				| EventType.UNPAY_ORDER_LIST;
	}

	@Override
	public void handleEvent(EventInfo event) {
		Log.d(TAG, "handleEvent: event=" + event.eventType);
		FragmentTransaction ft = mFragmentManager.beginTransaction();
		if (event.eventType == EventType.STORE_CONTENT) { // tab for store .
			removeFragment(frgCityList, FRAGMENT_CITYLIST_NAME);
			if (frgStore == null) {
				frgStore = new StoreFragment();
			}
			this.mEventInfo = event;
			addFragment(ft, frgStore, FRAGMENT_STORE_NAME);
			showFragment(frgStore, frgCard, frgCollent, frgAccount,
					unpayFormFrag);
		} else if (event.eventType == EventType.CARDBAG_CONTENT) { // tab for my
																	// card .
			removeFragment(frgCityList, FRAGMENT_CITYLIST_NAME);
			this.mEventInfo = event;
			if (frgCard == null) {
				frgCard = new MyCardFragment();
			}
			addFragment(ft, frgCard, FRAGMENT_CARDBAG_NAME);
			showFragment(frgCard, frgStore, frgCollent, frgAccount,
					unpayFormFrag);
		} else if (event.eventType == EventType.COLLENT_CONTENT) { // tab for
																	// collection.
			removeFragment(frgCityList, FRAGMENT_CITYLIST_NAME);
			this.mEventInfo = event;
			if (frgCollent == null) {
				frgCollent = new CollentFragment();
			}
			addFragment(ft, frgCollent, FRAGMENT_COLLENT_NAME);
			showFragment(frgCollent, frgStore, frgCard, frgAccount,
					unpayFormFrag);
		} else if (event.eventType == EventType.ACCOUNT_CONTENT) { // tab for
																	// @me.
			removeFragment(frgCityList, FRAGMENT_CITYLIST_NAME);
			this.mEventInfo = event;
			if (frgAccount == null) {
				frgAccount = new AccountFragment();
			}
			addFragment(ft, frgAccount, FRAGMENT_ACCOUNT_NAME);
			showFragment(frgAccount, frgStore, frgCard, frgCollent,
					unpayFormFrag);
		} else if (event.eventType == EventType.ACCOUNT_TITLE_ACCOUNT) { // in
																			// logined
																			// page
																			// to
																			// update
																			// title.

			this.mEventInfo = event;
		} else if (event.eventType == EventType.ACCOUNT_TITLE_LOGIN) { // in
																		// loging
																		// page
																		// to
																		// update
																		// title.

			this.mEventInfo = event;
		} else if (event.eventType == EventType.ACCOUNT_TITLE_REGISTER) { // in
																			// register
																			// page
																			// to
																			// update
																			// title.

			this.mEventInfo = event;
		} else if (event.eventType == EventType.ACCOUNT_FIND_PASSWORD) { // in
																			// forget
																			// pass
																			// page
																			// to
																			// update
																			// title.

			this.mEventInfo = event;
		} else if (event.eventType == EventType.ACCOUNT_TITLE_CHANGE_PAS) { // in
																			// change
																			// page
																			// to
																			// update
																			// title.

			this.mEventInfo = event;
		} else if (event.eventType == EventType.ACCOUNT_DELETE_ALL_FRAGMENT) {// clear
																				// all
																				// fragments
			deleteAllFragment();
		} else if (event.eventType == EventType.ACCOUNT_DELETE_FRAGMENT) {
			String mark = (String) event.values;
			deleteFragmentByMark(mark);
		} else if (event.eventType == EventType.ACCOUNT_CITYLIST) {// switch
																	// city
																	// list.
			frgCityList = new CityListFragment();
			this.mEventInfo = event;
			addFragment(ft, frgCityList, FRAGMENT_CITYLIST_NAME);
			showFragment(frgCityList, frgStore, null, null);
		} else if (event.eventType == EventType.STORE_FILTER) { // jump to store
																// filter view.
			StoreFilterFragment storeFilter = new StoreFilterFragment();
			this.mEventInfo = event;
			addFragment(ft, storeFilter, FRAGMENT_STORE_FILTER_NAME);
			showFragment(storeFilter, null, null, null);
		} else if (event.eventType == EventType.UNPAY_ORDER_LIST) {

			if (unpayFormFrag == null) {
				unpayFormFrag = new UnpayFormFragment();
			}
			this.mEventInfo = event;
			addFragment(ft, unpayFormFrag, FRAGMENT_UNPAY_FORM_LIST);
			showFragment(unpayFormFrag, frgCard, frgStore, frgCollent,
					frgAccount);
		}
	}

	/**
	 * clear all fragments.
	 */
	private void deleteAllFragment() {
		Collection<Fragment> fragments = fragmentMap.values();
		for (Fragment arg0 : fragments) {
			if (arg0 != null) {
				FragmentTransaction ft = mFragmentManager.beginTransaction();
				ft.remove(arg0);
				ft.commit();
			}
		}
		fragmentMap.clear();
	}

	@Override
	public void eventsChanged() {

	}

	/**
	 * remove fragment.
	 * 
	 * @param fragment
	 * @param fragmentName
	 */
	private void removeFragment(Fragment fragment, String fragmentName) {
		if (fragmentMap.get(fragmentName) != null) {
			fragmentMap.remove(fragmentName);
			FragmentTransaction ft = mFragmentManager.beginTransaction();
			ft.remove(fragment);
			ft.commit();
		}
	}

	/** turn to login page */
	DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
			if (mEventInfo != null
					&& mEventInfo.eventType == EventType.ACCOUNT_TITLE_LOGIN) {
				return;
			}
			((AccountFragment) frgAccount).clear();
			removeFragment(frgAccount, FRAGMENT_ACCOUNT_NAME);
			mController.sendEvent(EventType.ACCOUNT_CONTENT);

			// mCurBtnClickMark = FRAGMENT_ACCOUNT_NAME;
		}
	};

	/** cancle */
	DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {

		}
	};

	/**
	 * clear fragment.
	 * 
	 * @param mark
	 *            flag
	 */
	private void deleteFragmentByMark(String mark) {
		Log.e(TAG, "deleteFragmentByMark:mark");
		if (mark.equals(FRAGMENT_STORE_NAME)) {
			frgStore = null;
		}
		Fragment fragment = fragmentMap.get(mark);
		if (fragment != null) {
			Log.e(TAG, "deleteFragmentByMark: is not null");
			fragmentMap.remove(mark);
			FragmentTransaction ft = mFragmentManager.beginTransaction();
			ft.remove(fragment);
			ft.commit();
		}
	}

	@Override
	public void cancelUpdate(Object... params) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onBackButtonClick() {
		FragmentTransaction ft = mFragmentManager.beginTransaction();
		addFragment(ft, unpayFormFrag, FRAGMENT_UNPAY_FORM_LIST);
		showFragment(frgCard, unpayFormFrag, frgStore, frgCollent, frgAccount);

	}

	private void showPromptAlertDialog() {
		
		Builder b = new AlertDialog.Builder(this).setTitle("没有可用的网络")
				.setMessage("请开启网络连接");
		b.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// network is more prior than GPS. then prompt user to open
				// network.
//				can't go to settings activity, alert user instead. 
				/*if (!Tools.openSetting(CardActivity.this,
						CommonValue.CLASS_SETTING_NETWORK)) {
					Toast.makeText(mContext, "请打开网络", Toast.LENGTH_SHORT)
							.show();
					mEventHandler.sendEmptyMessage(EventHandler.MSG_QUIT_APP);
				}*/
				Toast.makeText(mContext, "请打开网络", Toast.LENGTH_SHORT)
				.show();
				mEventHandler.sendEmptyMessage(EventHandler.MSG_QUIT_APP);
			}
		}).setNeutralButton("取消", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.cancel();
				mEventHandler.sendEmptyMessage(EventHandler.MSG_QUIT_APP);
			}
		}).create();
		b.setCancelable(false);
		b.show();
	}

	private final class EventHandler extends Handler {
		public final static int MSG_STAGE_ENVIRONMENT_CHECK = 0x10;
		public final static int MSG_STAGE_INITIALIZE = 0x11;
		public final static int MSG_STAGE_INITIALIZE_COMPLETE = 0x20;
		public final static int MSG_QUIT_APP = 0x30;

		public EventHandler(Looper looper) {
			super(looper);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {
			Log.d(TAG, "EventHandler: cmd=" + msg.what);
			switch (msg.what) {
			case MSG_STAGE_ENVIRONMENT_CHECK:
				if (!Tools.isNetworkConnected(mContext)) {
					showPromptAlertDialog();
				} else {
					this.sendEmptyMessage(MSG_STAGE_INITIALIZE);
				}
				break;

			case MSG_STAGE_INITIALIZE:
				if (!Tools.isNetworkConnected(mContext)) {
					this.sendEmptyMessage(MSG_STAGE_ENVIRONMENT_CHECK);
					return;
				}

				// initialize location manager.
				setLocationOption();
				mLocClient.start();
				
				// initialize city data manager.
				CityDataManager.instance().initialize(mContext);

				// initialize image cache.
				ImageCache.ImageCacheParams cacheParams = new ImageCache.ImageCacheParams(
						mContext, CommonValue.IMG_CACHE_PATH);
				cacheParams.memoryCacheEnabled = true;
				cacheParams.initDiskCacheOnCreate = true;
				ImageCache.instance().initialize(cacheParams);
				ImageDataManager.instance().setLoadingImage(R.drawable.loading);

				this.sendEmptyMessageDelayed(MSG_STAGE_INITIALIZE_COMPLETE,
						5000);
				break;
			case MSG_STAGE_INITIALIZE_COMPLETE:
				logoImage.setVisibility(View.GONE);
				mainLayout.setVisibility(View.VISIBLE);

				CityBean city = FunctionUtil.getSelectedCityInfo();
				if (city == null) {
					city = MyLocationManager.instance()
							.getCurrentLocatedCityByDevice();
					FunctionUtil.setSelectedCityInfo(city);
				}

				StoreTypeInfo type = FunctionUtil.getSelectedStoreType();
				if (type == null) {
					type = new StoreTypeInfo();
					type.setTypeId(CommonValue.STORE_TYPE_ID_ALL);
					type.setTypeName(mContext.getResources().getString(
							R.string.store_list_view_type_all));
					FunctionUtil.setSelectedStoreTypeInfo(type);
				}

				mController.sendEvent(EventType.STORE_CONTENT);
				break;
			case MSG_QUIT_APP:
				mController.deregisterAllEventHandlers();
				CardController.removeInstance(mContext);
				finish();
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	}

	private LocationClient mLocClient;

	private void setLocationOption() {
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);
		option.setCoorType("bd09ll");
		option.setServiceName("com.baidu.location.service_v2.9");
		option.setPoiExtraInfo(true);
		option.setAddrType("all");
		option.setScanSpan(10000);	// interval time is 10s.
		option.setPriority(LocationClientOption.NetWorkFirst);
		option.setPoiNumber(10);
		option.disableCache(true);
		mLocClient.setLocOption(option);
	}
}
